﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Infrastructure.ObjectModel;
using Microsoft.Xna.Framework.Content;
using Infrastructure.Managers;
using Microsoft.Xna.Framework.Graphics;
using B10_Ex02_EladLebovitch_034695114.Screens;

namespace B10_Ex02_EladLebovitch_034695114.ObjectModel
{
    public class BarrierLine : RegisteredComponent
    {
        private const float k_BarrierWidth = 44;
        private const float k_BarrierMargin = 1.5f;
        private const float k_LineHeight = 600 - 32 - 30 - 32;
        private const string k_TextrureName = @"Sprites\BarrierLine";
        private const float k_Vilocity = 40;
        private const float k_AccelSpeed = 0.15f;
        private const int k_LevelCycles = 4;

        private int m_NumOfBarriers;
        private List<Barrier> m_Barriers;
        private float m_BarriersMoved = 0;
        private float m_LineWidth;

        private int currentLevel 
        { 
            get; 
            set;
        }

        public ContentManager Content
        {
            get;
            set;
        }
        
        /// <summary>
        /// Creates an enemy matrix
        /// </summary>
        /// <param name="i_game">The owning game</param>
        /// <param name="i_EnemiesInRow">Enemies in row</param>
        /// <param name="i_EnemiesInCol">Enemies in col</param>
        public BarrierLine(Game i_game, int i_numOfBarriers)
                        : base(i_game)
        {
            // Init members
            m_NumOfBarriers = i_numOfBarriers;
            m_Barriers = new List<Barrier>();
            currentLevel = (this.Game.Services.GetService(typeof(GameFlow)) as GameFlow).CurrentLevel;
            this.Content = new ContentManager(Game.Services);

            Vector2 brVelocity;

            // Check the current level
            if (currentLevel % k_LevelCycles != 1)
            {
                brVelocity = new Vector2((k_Vilocity * (1 + k_AccelSpeed * (currentLevel % k_LevelCycles))), 0);
            }
            else
            {
                brVelocity = Vector2.Zero;
            }

            m_LineWidth = (k_BarrierWidth * i_numOfBarriers + k_BarrierWidth * k_BarrierMargin * (i_numOfBarriers - 2));
            float StartX = (i_game.GraphicsDevice.Viewport.Width - m_LineWidth) / 3;

            // Create Barriers
            for (int i = 0; i < m_NumOfBarriers; i++)
            {
                Barrier newBarrier = new Barrier(i_game, k_TextrureName, i, Content);
                newBarrier.TopLeftPosition = new Vector2(
                                                StartX + (i * k_BarrierWidth + (i * k_BarrierWidth * k_BarrierMargin)),
                                                k_LineHeight);
                newBarrier.Velocity = brVelocity;
                m_Barriers.Add(newBarrier);
                ((MainGameScreen)i_game.Services.GetService(typeof(MainGameScreen))).Add(newBarrier);
                newBarrier.ColidedAndChanged += new ColidedEventHandler(newBarrier_ColidedAndChanged);
            }
        }

        private void newBarrier_ColidedAndChanged(object i_Collidable)
        {
            // Barrier colided
            Barrier Colided = i_Collidable as Barrier;

            foreach (Barrier barier in this.m_Barriers)
            {
                if (barier != Colided)
                {
                    barier.Texture = Colided.Texture;
                }
            }
        }

        public override void Update(GameTime gameTime)
        {
            // Move Barriers
            if (currentLevel % k_LevelCycles != 1)
            {
                float MovedNow = (float)gameTime.ElapsedGameTime.TotalSeconds *
                                 (k_Vilocity * (1 + k_AccelSpeed * (currentLevel % k_LevelCycles)));
                m_BarriersMoved += Math.Abs(MovedNow);

                if (m_BarriersMoved >= m_LineWidth / 2)
                {
                    foreach (Barrier brr in m_Barriers)
                    {
                        brr.Velocity *= -1;
                    }

                    m_BarriersMoved = 0;
                }
            }

            base.Update(gameTime);
        } 
    }
}
